<?php
class Process {
	private $_sPath;
	private $_iTimeout;
	private $_iLimit;
	
	public function __construct() {
		self::setDir ();
		self::setLimit ();
		self::setTimeout ();
	}
	
	public function setDir($sPath = null) {
		try {
			$sPath = $sPath ? $sPath : Base::getConf ( 'process.path' );
			if ($sPath == null) {
				if (! realpath ( ROOT . '/process' )) {
					throw new ExceptionExt ( '进程目录' . $sPath . '不存在' );
				} else {
					$sPath = ROOT . '/process';
				}
			} elseif (! realpath ( $sPath )) {
				if (! realpath ( ROOT . '/' . $sPath )) {
					throw new ExceptionExt ( '进程目录' . $sPath . '不存在' );
				} else {
					$sPath = ROOT . '/process';
				}
			}
		} catch ( ExceptionExt $e ) {
			$e->showError ();
		}
		$this->_sPath = $sPath;
	}
	
	public function setTimeout($iTime = null) {
		if ($iTime == null) {
			$iTime = Base::getConf ( 'process.time' );
			if ($iTime == null) {
				$iTime = 300;
			}
		}
		$this->_iTimeout = $iTime;
	}
	
	public function setLimit($iLimit = null) {
		if ($iLimit == null) {
			$iLimit = Base::getConf ( 'process.limit' );
			if ($iLimit == null) {
				$iLimit = 20;
			}
		}
		$this->_iLimit = $iLimit;
	}
	
	public function start($sShell) {
		self::clear ();
		$process = scandir ( $this->_sPath );
		
		if (count ( $process ) - 2 < $this->_iLimit) {
			list ( $mico, $sec ) = split ( ' ', microtime () );
			$pid = $sec . substr ( $mico, 2, - 2 );
			$pidFile = $this->_sPath . '/' . $pid;
			$cmd = $sShell . ' ' . $pid;
			file_put_contents ( $pidFile, $cmd );
			exec ( $cmd . ' >null &' );
			return true;
		} else {
			usleep ( 200 );
			self::start ( $sShell );
		}
		return true;
	}
	
	public function end($iPid) {
		@unlink ( $this->_sPath . '/' . $iPid );
	}
	
	public function clear() {
		if ($this->_iTimeout > 0) {
			if (rand ( 0, 10 ) == 0) {
				$aFiles = scandir ( $this->_sPath );
				$iCount = count ( $aFiles );
				for($i = 2; $i < $iCount; $i ++) {
					if (time () - $this->_iTimeout > @filemtime ( $this->_sPath . '/' . $aFiles [$i] )) {
						@unlink ( $this->_sPath . '/' . $aFiles [$i] );
					}
				}
			}
		}
	}
}
?>